#include "protocol.h"
#include "gprs.h"
#include "comm.h"
#include "rtdevice.h"
#include "appconfig.h"

#ifdef USING_DEBUG_SERVER
char SERVER_IP[32] = "develop.in.3322.org";
int SERVER_PORT     =  15614 ;
#else
char SERVER_IP[32]= "dzbq.bdjh8.com";//"125.67.236.55"
int SERVER_PORT=       8099;
#endif


rt_event_t update_evt = RT_NULL;


rt_uint8_t elsPicBuf1[ELS_PIC_BUF_SIZE]={0};

rt_uint8_t *show_buffer_get(void)
{
	return elsPicBuf1;
}

rt_err_t affirm_mod_finsh(rt_uint8_t type,rt_uint8_t *value)
{
	msgFinshModReqDef *modFReq;
	msgFinshModAckDef *modFAck;
	devInfodef *info;
	rt_int8_t iresult;
	rt_err_t result;
	
	//分配资源
	modFAck = rt_calloc(1, sizeof(msgFinshModAckDef));
	RT_ASSERT(modFAck);
	modFReq = rt_calloc(1,sizeof(msgFinshModReqDef));
	RT_ASSERT(modFReq);
	info = devinfo_get();

	//准备数据
	modFReq->msg.cmd = Cmd_modFinshReq;
	modFReq->msg.type = type;
	uint32_to_str(info->mac,modFReq->msg.id);
	uint16_to_str(sizeof(*modFReq), modFReq->msg.len);
	//建立链接
	//iresult = gsm_gprs_connect(1,SERVER_IP,SERVER_PORT,1000);//链接后台
	iresult = 0;
	if(iresult == 0)
	{
		//发送数据
		rt_uint16_t sendSize;
		rt_uint16_t recvSize;

		sendSize = sizeof(*modFReq);
		recvSize = sizeof(*modFAck);
		iresult = gsm_send_gprs_OSPF(modFReq->buf, sendSize, modFAck->buf, &recvSize, 500);
		if(iresult == 0)//发送成功
		{
			//计算流量
			info->flow += (TCP_FIX_BNUM + sendSize + recvSize);
			//解析数据
			if(modFAck->msg.cmd == Cmd_modFinshAck)//命令正确
			{
				rt_kprintf("Mod result %d\n",modFAck->msg.result);
				(*value) = modFAck->msg.result;
				result = RT_EOK;
			}
			else
			{
				result = RT_ERROR;
			}
		}
		else
		{
			result = RT_ERROR;
		}
	}
	else
	{
		result = RT_ERROR;
	}

	//断开链接
	gsm_switch_cmd(0,RT_NULL);//退出透传
	gsm_gprs_connect(0,SERVER_IP,SERVER_PORT,100);

	rt_free(modFAck);
	rt_free(modFReq);

	return result;
}

rt_err_t server_mod_sleep(void)
{
	msgAskCycleReqDef *askCycleReq;
	msgAskCycleAckDef *askCycleAck;
	rt_err_t result = RT_ERROR;
	rt_int8_t iresult;
	devInfodef *info;
	rt_int8_t csq;//信号值
	rt_uint16_t crc16;

	//分配资源
	askCycleReq = rt_calloc(1,sizeof(msgAskCycleReqDef));
	RT_ASSERT(askCycleReq)
	askCycleAck = rt_calloc(1,sizeof(msgAskCycleAckDef));
	RT_ASSERT(askCycleAck)
	info = devinfo_get();

	//准备数据
	askCycleReq->msg.cmd = Cmd_askCycModReq;
	uint16_to_str(sizeof(msgAskCycleReqDef)-2, askCycleReq->msg.len);
	uint32_to_str(info->mac, askCycleReq->msg.id);
	crc16 = net_crc16(&askCycleReq->buf[2],sizeof(askCycleReq)-4);//计算crc16
	uint16_to_str(crc16, askCycleReq->msg.crc);
	
	
	//启动gsm
	iresult = gprs_module_start(&csq, 1);
	if(iresult == -1)//启动失败
	{
		rt_free(askCycleReq);
		rt_free(askCycleAck);
		rt_kprintf("GSM Is Close %d\n",iresult);
		return result;
	}
	
	//发送数据
	result = gprs_connet_resend(gsm_gprs_connect,1,(char *)info->url,info->port,1000);
	if(result == RT_EOK)
	{
		rt_uint16_t recvSize;

		recvSize = sizeof(*askCycleAck);
		iresult = rsend_gprs_data(askCycleReq->buf,sizeof(*askCycleReq),askCycleAck->buf,&recvSize,500);
		info->flow += (TCP_FIX_BNUM+recvSize+sizeof(*askCycleReq));//计算流量
		if((iresult == 0)&&(recvSize > 4))
		{
			rt_uint16_t netCRC16;

			netCRC16 = net_crc16(&askCycleAck->buf[2], recvSize-4);
			crc16 = str_to_uint16(&askCycleAck->buf[recvSize-2]);
#ifndef USEING_NET_CRC16
			crc16 = netCRC16;
#endif
			if(crc16 == netCRC16)
			{
				if(askCycleAck->msg.cmd == Cmd_askCycModAck)//应答命令正确
				{
					rt_uint16_t time;
					rt_uint8_t finsh;
					rt_uint16_t *curCycle;
					rt_uint16_t oldCycle;
					
					time = str_to_uint16(askCycleAck->msg.time);
					curCycle = (rt_uint16_t*)update_ask_cycle_get();//睡眠时间
					oldCycle = *curCycle;
					if(time < UPDATE_CYCLIE_MIN)//小于1分钟
					{
						(*curCycle) = UPDATE_CYCLIE_MIN;
					}
					else
					{
						(*curCycle) = time;
						rt_kprintf("mod sleep cyclie %d s\n",time);
					}
				
					//发送完成请求
					result = affirm_mod_finsh(1,&finsh);//发送 修改完成 并且 关闭链接
					if(result == RT_EOK)//成功完成修改。
					{
						//更新模拟EEPROM中的保存数据
						info->cycle = (*curCycle);
						result =	devinfo_save();//保存数据到Flash
						//调整本次睡眠周期
						set_system_stop_cycle(info->cycle);//(当前时间-修改时间)%更新周期(本次休眠时间)
						send_epd_mail(EPD_EVT_FULL);//事件查询
					}
					else//应答失败，服务器不知道改了所以不改。
					{
						(*curCycle) = oldCycle;
						rt_kprintf("Mod Fail%s %s\n",__FUNCTION__,__LINE__);
					}
				}
				else//命令错误
				{
					rt_kprintf("recv msg CMD error %x\n",askCycleAck->msg.cmd);
				}
			}
			else//crc错误
			{
				rt_kprintf("recv msg CRC16 error %x != %x\n",crc16,netCRC16);
			}
		}
		else//发送失败
		{
			result =	RT_ERROR;
		}
	}
	else//链接服务器失败
	{
		result = RT_ERROR;
	}
	//断开链接
	gsm_switch_cmd(0,RT_NULL);//退出透传
	gsm_gprs_connect(0,(char *)info->url,info->port,100);

	rt_free(askCycleReq);
	rt_free(askCycleAck);

	return result;
}

rt_err_t server_update_url(void)
{
	msgModUrlReqDef *msgReq;
	msgModUrlAckDef *msgAck;
	rt_err_t result = RT_ERROR;
	rt_int8_t iresult;
	devInfodef *info;
	rt_int8_t csq;//信号值
	rt_uint8_t reboot = 0;
	rt_uint16_t crc16;//crc16

	info = devinfo_get();
	//分配资源
	msgReq = rt_calloc(1,sizeof(msgModUrlReqDef));
	RT_ASSERT(msgReq)
	msgAck = rt_calloc(1,sizeof(msgModUrlAckDef));
	RT_ASSERT(msgAck)
	

	//准备数据
	msgReq->msg.cmd = Cmd_modURLReq;
	uint16_to_str(sizeof(msgModUrlReqDef)-2, msgReq->msg.len);//长度=命令+数据+crc16
	uint32_to_str(info->mac, msgReq->msg.id);
	crc16 = net_crc16(&msgReq->buf[2],sizeof(*msgReq)-4);//计算CRC16
	uint16_to_str(crc16,msgReq->msg.crc);//填充CRC16
	
	//启动gsm
	iresult = gprs_module_start(&csq, 1);
	if(iresult == -1)//启动失败
	{
		rt_free(msgReq);
		rt_free(msgAck);
		rt_kprintf("GSM Is Close %d\n",iresult);
		return result;
	}
	
	//发送数据
	result = gprs_connet_resend(gsm_gprs_connect,1,(char *)info->url,info->port,1000);
	if(result == RT_EOK)
	{
		rt_uint16_t recvSize;
		
		recvSize = sizeof(*msgAck);
		rt_kprintf("recvSize = %d\n",recvSize);
		rt_kprintf("sizeof(msgModUrlAckDef) = %d\n",sizeof(msgModUrlAckDef));
		rt_kprintf("sizeof(modUrlAckDef) = %d\n",sizeof(modUrlAckDef));
		iresult = rsend_gprs_data(msgReq->buf,sizeof(*msgReq),msgAck->buf,&recvSize,500);
		rt_kprintf("recvSize = %d\n",recvSize);
		info->flow += (TCP_FIX_BNUM+recvSize+sizeof(*msgReq));//计算流量
		if((iresult == 0) && (recvSize > 4))//接收数据长度要够，发送接收处理结果正常
		{
			rt_uint16_t netCRC16;
			
			crc16 = str_to_uint16(msgAck->msg.crc);//提出crc
			netCRC16 = net_crc16(&msgAck->buf[2],recvSize-4);
#ifndef USEING_NET_CRC16
			crc16 = netCRC16;
#endif
			if(crc16 == netCRC16)//crc校验成功
			{
				if(msgAck->msg.cmd == Cmd_modURLAck)//应答命令正确
				{
					rt_uint8_t finsh;
					
					info->port = str_to_uint16(msgAck->msg.port);
					rt_memset(info->url, 0, 32);
					rt_memcpy(info->url, msgAck->msg.url, rt_strlen((const char *)msgAck->msg.url));
					rt_kprintf("new url %s port %d %d\n",info->url,info->port,rt_strlen((const char *)msgAck->msg.url));
				
					//发送完成请求
					result = affirm_mod_finsh(2,&finsh);//发送 修改完成 并且 关闭链接
					if(result == RT_EOK)
					{
						//保存重启设备
						result =	devinfo_save();
						if(result == RT_EOK)//保存成功
						{
							reboot = 1;
						}
					}
					else
					{
						rt_kprintf("Mod url Fail%s %d\n",__FUNCTION__,__LINE__);
						result = RT_ERROR;
					}
				}
				else//命令错误
				{
					rt_kprintf("recv msg CMD error %x \n",msgAck->msg.cmd);
					result = RT_ERROR;
				}
			}
			else//crc错误
			{
				rt_kprintf("crc error %d != %d\n",crc16,netCRC16);
				result = RT_ERROR;
			}
		}
		else//发送失败
		{
			result =	RT_ERROR;
		}
	}
	else//链接服务器失败
	{
		result = RT_ERROR;
	}
	
	//断开链接
	gsm_switch_cmd(0,RT_NULL);//退出透传
	gsm_gprs_connect(0,(char *)info->url,info->port,100);

	//释放资源
	rt_free(msgReq);
	rt_free(msgAck);

	if(reboot == 1)
	{
		sys_reboot();//重启系统
	}
	return result;
}


rt_err_t dev_server_ask(void)
{
	msgAskEvtReqDef *askReq;
	msgAskEvtAckDef *askAck;
	rt_int8_t iresult;
	rt_err_t result;
	devInfodef *info;
	rt_uint16_t crc16;
	rt_uint8_t gsmclose;

	gsmclose = 0;

	//分配资源
	askReq = rt_calloc(1,sizeof(msgAskEvtReqDef));
	RT_ASSERT(askReq);
	askAck = rt_calloc(1,sizeof(msgAskEvtAckDef));
	RT_ASSERT(askAck);
	info = devinfo_get();
	result = RT_EOK;

	//启动GSM
	iresult = gprs_module_start(&(info->csq), 1);
	if(iresult == -1)//启动失败
	{
		rt_free(askReq);
		rt_free(askAck);
		rt_kprintf("GSM Is Close %d\n",iresult);
		return result;
	}
	//准备数据
	askReq->msg.cmd = Cmd_askEvtReq;
	askReq->msg.csq = info->csq;
	askReq->msg.vbat = info->vbat;
	uint16_to_str(sizeof(*askReq)-2, askReq->msg.len);
	uint32_to_str(info->flow, askReq->msg.flow);
	uint16_to_str(info->charge, askReq->msg.charge);
	uint32_to_str(info->mac, askReq->msg.id);
	crc16 = net_crc16(&askReq->buf[2],sizeof(msgAskEvtReqDef)-4);
	uint16_to_str(crc16, askReq->msg.crc);//填充crc16
	
	//链接服务器发送
	result = gprs_connet_resend(gsm_gprs_connect,1,(char *)info->url,info->port,1000);
	//iresult = gsm_gprs_connect(1,(char *)info->url,info->port,1000);//链接后台
	if(result == RT_EOK)//链接成功
	{
		rt_uint16_t recvLen;

		recvLen = sizeof(*askAck);
		rt_kprintf("send len=%d recv len=%d\n",sizeof(*askReq),sizeof(*askAck));
		iresult = rsend_gprs_data(askReq->buf,sizeof(*askReq),askAck->buf, &recvLen, 500);
		info->flow += (TCP_FIX_BNUM+recvLen+sizeof(*askReq));//统计流量
		if((iresult == 0) && (recvLen > 4))//接收数据成功
		{
			rt_uint16_t netCRC16;
			
			crc16 = str_to_uint16(askAck->msg.crc);//提出crc
			rt_kprintf("crc16=%x\n",crc16);
			netCRC16 = net_crc16(&askAck->buf[2], recvLen-4);//计算crc16
#ifndef USEING_NET_CRC16
			crc16 = netCRC16;
#endif
			if(crc16 == netCRC16)//crc校验通过
			{
				if(askAck->msg.cmd == Cmd_askEvtAck)//命令正常
				{
					rt_uint32_t date;
					date = str_to_uint32(askAck->msg.date);
					//保存时间				
					update_rtc_value(date);
					date_show(date);
					cur_date_show();
				
					//分析事件
					if(askAck->msg.evt1 & Ask_URL)//更新url
					{
						update_event_mail(PRO_EVT_URL);
					}
					if(askAck->msg.evt1 & Ask_Gap)//更新间隔
					{
						update_event_mail(PRO_EVT_UAT);
					}
					if(askAck->msg.evt1 & Ask_PIC)//更新图片
					{
						update_event_mail(PRO_EVT_KEY);
					}
					else//没有任何事件，gsm可以关闭链接
					{
						gsmclose = 1;
					}
				}
			}
			else//crc校验出错
			{
				rt_kprintf("crc error %d != %d\n",crc16,netCRC16);
				result = RT_ERROR;
			}
		}
		else//接收数据失败
		{
			result = RT_ERROR;
		}
	}
	else
	{
		result = RT_ERROR;
	}
	//断开链接
	gsm_switch_cmd(0,RT_NULL);//退出透传
	gsm_gprs_connect(0,(char *)info->url,info->port,100);

	if(gsmclose == 1)//没有网络通讯了
	{
		gprs_module_stop();//GSM关机
	}
	
	//释放资源
	rt_free(askReq);
	rt_free(askAck);
	return result;
}

rt_err_t dev_server_reg(void)
{
	msgDevRegReqDef *regReq;
	msgDevRegAckDef *regAck;
	rt_int8_t iresult;
	rt_err_t result;
	devInfodef *info;
	rt_uint16_t crc16;

	iresult = -1;
	result = RT_EOK;
	info = devinfo_get();
	//分配资源
	regReq = rt_calloc(1,sizeof(msgDevRegReqDef));
	RT_ASSERT(regReq);
	regAck = rt_calloc(1,sizeof(msgDevRegAckDef));
	RT_ASSERT(regAck);

	//准备注册数据
	regReq->msg.cmd = Cmd_DevRegReq;
	regReq->msg.cpu = SYS_CPU_TYPE;
	regReq->msg.csq = info->csq;
	get_dev_mac(regReq->msg.id);
	regReq->msg.vbat = info->vbat;
	uint16_to_str(sizeof(msgDevRegReqDef)-2, regReq->msg.len);
	crc16 = net_crc16(&regReq->buf[2], sizeof(msgDevRegReqDef)-4);//计算crc
	uint16_to_str(crc16, regReq->msg.crc);
	rt_kprintf("crc16 = %x\n",crc16);
	//启动gsm
	iresult = gprs_module_start(&(info->csq), 1);
	if(iresult != 0)//启动失败
	{
		update_event_mail(PRO_EVT_REG);//重新注册

		//释放资源
		rt_free(regAck);
		rt_free(regReq);
		return RT_ERROR;
	}
	rt_kprintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%s\n",info->url);
	//发送、接受报文
	//iresult = gsm_gprs_connect(1,(char *)info->url,info->port,1000);//链接后台
	result = gprs_connet_resend(gsm_gprs_connect,1,(char *)info->url,info->port,1000);
	if(result == RT_EOK)//链接成功
	{
		rt_uint16_t recvLen;

		recvLen = sizeof(*regAck);
		rt_kprintf("recvLen=%d\n",recvLen);
		iresult = rsend_gprs_data(regReq->buf,sizeof(*regReq), regAck->buf, &recvLen, 500);
		info->flow += (recvLen+sizeof(*regReq)+TCP_FIX_BNUM);
		if((iresult == 0) && (recvLen > 4))//接收数据成功
		{
			rt_uint16_t netCRC16;
			
			//校验CRC
			crc16 = str_to_uint16(regAck->msg.crc);//取出crc
			rt_kprintf("crc16 = %x\n",crc16);
			netCRC16 = net_crc16(&regAck->buf[2], recvLen-4);
#ifndef USEING_NET_CRC16
			crc16 = netCRC16;
#endif			
			if(crc16 == netCRC16)//CRC校验成功
			{
				if(regAck->msg.cmd == Cmd_DevRegAck)//命令正确
				{
					//rt_uint32_t date;
	
					//date = str_to_uint32(regAck->msg.date);
					//更新系统时间,改到查询函数同步时间
					switch(regAck->msg.result)//处理结果
					{
						case 0://成功
						case 1://设备已经过了注册
						{
							info->mac = str_to_uint32(regAck->msg.mac);
							info->regFlag = 1;
							devinfo_save();
							rt_kprintf("dev reg ok,get mac=%d\n",info->mac);
							result = RT_EOK;
							//注册成功后去查询事件。
							update_event_mail(PRO_EVT_ASK);
							break;
						}
						case 2://等待审核
						{
							result = RT_ERROR;
							break;
						}
					}
				}
				else//命令错误
				{
					rt_kprintf("recv net msg CMD error %x\n",regAck->msg.cmd);
					result = RT_ERROR;
				}
			}
			else//校验失败
			{
				rt_kprintf("recv net msg crc error %x != %x\n",crc16,netCRC16);
				result = RT_ERROR;
			}
		}
		else//接收失败
		{
			result = RT_ERROR;
			//处理重发
		}
	}
	else//链接失败
	{
		result = RT_ERROR;
	}
	//解析注册数据

	//断开链接
	gsm_switch_cmd(0,RT_NULL);//退出透传
	gsm_gprs_connect(0,(char *)info->url,info->port,100);
	
	//释放资源
	rt_free(regAck);
	rt_free(regReq);

	return result;
}

/* --------------------------------------------------------------------------*/
/**
 * @Synopsis  服务器获取文件
 *
 * @Param type
 * @Param id
 * @Param bufSize
 *
 * @Returns   
 */
/* ----------------------------------------------------------------------------*/
rt_int8_t get_server_file(rt_uint8_t type,rt_uint32_t id,rt_uint16_t bufSize)
{
	msgFileInfoReqDef *msgFileInfoReq;
	msgFileInfoAckDef msgFIA;
	msgFileDataReqDef msgFDR;
	msgFileDataAckDef *msgFDA;
	msgFileFinshReqDef msgFFQ;
	msgFileFinshAckDef msgFFA;
	//rt_uint8_t *recv,*hRecv;
	rt_uint16_t size;
	rt_uint32_t fileID;
	rt_uint32_t fileSize;
	rt_uint16_t packNum;
	rt_uint8_t i;
	rt_int8_t result;
	rt_err_t eresult;
	devInfodef *info;
	rt_uint16_t recvLen=0;
	rt_uint8_t reSendNum = 0;
	rt_uint16_t crc16;

	info = devinfo_get();	
	msgFDA = rt_calloc(1, sizeof(msgFileDataAckDef));//文件数据请求应答
	RT_ASSERT(msgFDA);
	//hRecv = recv = rt_calloc(1,GSM_READ_LEN);
	//RT_ASSERT(hRecv);
	msgFileInfoReq = rt_calloc(1, sizeof(msgFileInfoReqDef));
	RT_ASSERT(msgFileInfoReq);

	//链接服务器
	eresult = gprs_connet_resend(gsm_gprs_connect,1,(char *)info->url,info->port,1000);
	if(eresult == RT_EOK)//连接服务器成功。
	{
		recvLen = sizeof(msgFileInfoAckDef);
		uint16_to_str(sizeof(msgFileInfoReqDef)-2,msgFileInfoReq->msg.len);
		msgFileInfoReq->msg.cmd = cmd_fileInfoReq;
		uint32_to_str(id,msgFileInfoReq->msg.id);
		uint16_to_str(bufSize,msgFileInfoReq->msg.size);//包大小
		msgFileInfoReq->msg.type =  type;

		//show_hex_string(&msgFileInfoReq->buf[2], sizeof(*msgFileInfoReq)-4);
		crc16 = net_crc16(&msgFileInfoReq->buf[2], sizeof(*msgFileInfoReq)-4);
		//rt_kprintf("crc16 = %x %x\n",crc16,net_crc16("\x03\x00\x00\x00\x02\x01\x02\x00",8));
		
		uint16_to_str(crc16,msgFileInfoReq->msg.crc);//填充crc16
		
		size = sizeof(msgFileInfoReqDef);
		rt_kprintf("send size:%d\n",size);
		result = rsend_gprs_data(msgFileInfoReq->buf,size,msgFIA.buf,&recvLen,500);//发送请求
		info->flow +=(TCP_FIX_BNUM+size+recvLen);//先统计流量
		if((result == 0) && (recvLen > 4))
		{
			rt_uint16_t netCRC16;

			netCRC16 = net_crc16(&msgFIA.buf[2], recvLen-4);
			crc16 = str_to_uint16(msgFIA.msg.crc);//提取crc16的值
			//rt_memcpy(msgFIA.buf,hRecv, sizeof(msgFileInfoAckDef));
			#ifndef USEING_NET_CRC16
			crc16 = netCRC16;
			#endif
			if(crc16 == netCRC16)//crc16 校验成功
			{
				if(msgFIA.msg.cmd == 0x83)//命令正确
				{
					rt_kprintf("cmd=%x\n",msgFIA.msg.cmd);
					fileID = str_to_uint32(msgFIA.msg.fileID);
					fileSize = str_to_uint32(msgFIA.msg.fileSize);
					packNum = str_to_uint16(msgFIA.msg.packNum);
					rt_kprintf("fileID=%d\n",fileID);
					rt_kprintf("fileSize=%d\n",fileSize);
					rt_kprintf("packNum=%d\n",packNum);
				
					if(packNum*bufSize > ELS_PIC_BUF_SIZE)
					{
						packNum = ELS_PIC_BUF_SIZE/bufSize;
					}
				
					//开始传输数据包
					//rt_memset(recv, 0, GSM_READ_LEN);
					//hRecv = recv;
					reSendNum = 0;//重发计数
					for(i=0; i<packNum;i++)
					{
						//rt_uint16_t recvLen;
						rt_uint16_t packPos;
						rt_uint16_t crc16;
				
						size = sizeof(msgFileDataReqDef);//发送长度
						recvLen = sizeof(msgFileDataAckDef);//接收长度
						rt_kprintf("%d pack gprs send result=%d\n",i,result);
						//rt_memset(recv, 0, GSM_READ_LEN);
						msgFDR.msg.cmd = Cmd_fileDataReq;//请求数据包
						uint16_to_str(sizeof(msgFDR)-2, msgFDR.msg.len);
						uint32_to_str(id, msgFDR.msg.devID);//设备ID
						uint32_to_str(fileID,msgFDR.msg.picID);//图片ID
						uint16_to_str(i, msgFDR.msg.pos);//图片包位置
						crc16 = net_crc16(&msgFDR.buf[2],size-4);
						uint16_to_str(crc16,msgFDR.msg.crc);//crc16
						
						result = rsend_gprs_data(msgFDR.buf,size,msgFDA->buf,&recvLen,1000);
						info->flow += (TCP_FIX_BNUM+size+recvLen);
						if((result == 0) && (recvLen > 4))//收发成功
						{
							rt_uint16_t netCRC16;
							//CRC校验
							crc16 = str_to_uint16(&msgFDA->buf[recvLen-2]);
							netCRC16 = net_crc16(&msgFDA->buf[2], recvLen-4);
#ifndef USEING_NET_CRC16
							crc16 = netCRC16;//没有使用CRC16
#endif
							if(netCRC16 == crc16)//包没有问题
							{
								//保存数据
								if(msgFDA->msg.cmd == Cmd_fileDataAck)
								{
									//rt_memcpy(msgFDA->buf ,(const char *)recv, sizeof(msgFileDataAckDef));
									packPos = str_to_uint16(msgFDA->msg.pos);//包位置
									if(packPos*bufSize <= ELS_PIC_BUF_SIZE)
									{
										rt_memcpy(&elsPicBuf1[packPos*bufSize],msgFDA->msg.data, bufSize);
									}
									else//文件太大
									{
										result = 1;
										break;
									}
								}
								else//失败
								{
									result = 2;
									break;
								}
							}
							else//crc错误接收有问题
							{
								if(reSendNum++ < 3)//上一包重发三次，每次还会重发三次，一个包发6次失败就不发了。
								{
									rt_kprintf("crc16 error %x != %X resend %d\n",crc16,netCRC16,reSendNum);
									i--;
									continue;
								}
								else//不发了
								{
									result = 3;//crc错误
									reSendNum = 0;
									rt_kprintf("crc16 error %x != %X \n",crc16,netCRC16);
									break;
								}
							}
						}
					}
					//发送传输完成
					recvLen = sizeof(msgFileFinshAckDef);
					uint16_to_str(sizeof(msgFileFinshReqDef)-2,msgFFQ.msg.len);
					msgFFQ.msg.cmd = Cmd_fileFinshReq;
					msgFFQ.msg.result = result;//处理结果
					uint32_to_str(id, msgFFQ.msg.devID);
					uint32_to_str(fileID, msgFFQ.msg.picID);
					crc16 = net_crc16(&msgFFQ.buf[2],sizeof(msgFFQ)-4);
					uint16_to_str(crc16,msgFFQ.msg.crc);
					size = sizeof(msgFileFinshReqDef);
					rsend_gprs_data(msgFFQ.buf, size,msgFFA.buf,&recvLen,500);//发送05报文
					info->flow += (TCP_FIX_BNUM+size+recvLen);
				}
				else//命令不对
				{
					static rt_uint8_t errnum=0;
				
					if( errnum++ == 1 )//三次不对可能是服务器地址错误
					{
						SERVER_PORT = info->port;
						rt_strncpy((char *)info->url, "118.184.176.34", rt_strlen("118.184.176.34"));
					}
					rt_kprintf("0x83 cmd error\n");
					result = -1;
				}
			}
			else//校验错误
			{
				rt_kprintf("recv msg crc16 error %x != %x\n",crc16,netCRC16);
			}
		}
		else//发送失败
		{
			rt_kprintf("send msg fail!!!!\n");
		}
	}
	else//链接失败
	{
		result = -1;
		rt_kprintf("connet sever fail...%d\n",result);
	}
	gsm_switch_cmd(0,RT_NULL);//退出透传
	gsm_gprs_connect(0,SERVER_IP,SERVER_PORT,100);

	//释放资源	
	rt_free(msgFileInfoReq);
	rt_free(msgFDA);
	//rt_free(recv);
	
	return result;
}

void update_event_mail(rt_uint32_t evt)
{
	rt_event_send(update_evt,evt);
}
static rt_timer_t key_event_timer;

void key_evnet_timeout(void *arg)
{
	if(rt_pin_read(KEY_GPIO_PIN) == 1)
	{
		rt_kprintf("key Trigger\n");
		update_event_mail(PRO_EVT_KEY);
	}
}
void key_event_process(void *arg)
{
	rt_timer_start(key_event_timer);
}

int key_event_init(void)
{
	rt_pin_mode(KEY_GPIO_PIN,PIN_MODE_INPUT_PULLDOWN); //开机脚
	rt_pin_attach_irq(KEY_GPIO_PIN,PIN_IRQ_MODE_RISING,key_event_process,RT_NULL);
	pin_irq_enable(KEY_GPIO_PIN,PIN_IRQ_ENABLE);
	key_event_timer = rt_timer_create("t_key",
										key_evnet_timeout,
										RT_NULL,
										10,
										RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
	return 0;
}
INIT_DEVICE_EXPORT(key_event_init);


static rt_timer_t epd_timer;

void epd_timer_process(void *arg)
{
	send_epd_mail(EPD_EVT_UPDATE);
	//rt_kprintf("__________________________________________________________________\n");
}

void epd_timer_start(void)
{
	send_epd_mail(EPD_EVT_PART);
	rt_timer_start(epd_timer);
}

void epd_timer_stop(void)
{
	rt_timer_stop(epd_timer);
	send_epd_mail(EPD_EVT_CLOSE);
}

void epd_timer_init(void)
{
	epd_timer = rt_timer_create("t_epd",
									epd_timer_process,
									RT_NULL,
									50,
									RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER);
}


rt_err_t update_server_pic(rt_uint8_t *err,rt_uint32_t evt)
{
	devInfodef *info;
	rt_int8_t result;
	rt_uint8_t run;

	epd_timer_start();//启动下周提示寄存器
	info = devinfo_get();
	result = gprs_module_start(&(info->csq),1);
	rt_kprintf("gprs_module_start() result = %d\n",result);
	if(result == -1)
	{
		(*err)++;
		if((*err) < GSM_START_ERR_MAX)
		{
			update_event_mail(evt);
			return RT_ERROR;
		}
	}
	else
	{
		(*err) = 0;
	}

	//下载3次，又一次成功就退出
	run = 3;
	do
	{
		result = get_server_file(1,info->mac,512);
		if(result == 0)//下载成功
		{
			break;
		}
	}while(run--);
	//gprs_module_stop();
	epd_timer_stop();
	if(result == 0)//数据更新成功
	{
		rt_kprintf("save data start...\n");
		cur_date_show();
		send_epd_mail(EPD_EVT_FULL);//事件查询
		eeprom_save_data(elsPicBuf1);
		rt_kprintf("save data finsh\n");
		cur_date_show();
	}
	else//更新失败，显示原来的图片
	{
		rt_uint8_t *buf;

		buf = show_buffer_get();
		eeprom_load_data(buf);
		send_epd_mail(EPD_EVT_FULL);
		return RT_ERROR;
	}

	return RT_EOK;
}


rt_err_t devinfo_init_process(void)
{
	rt_err_t result = RT_EOK;
	
	result = devinfo_loader();
	if(result == RT_EOK)//加载成功
	{
		devInfodef *devInfo;
		devInfo = devinfo_get();
		rt_kprintf("devInfo->mac       = %d\n",devInfo->mac);
		rt_kprintf("devInfo->regFlag   = %d\n",devInfo->regFlag);
		rt_kprintf("devInfo->url       = %s\n",devInfo->url);
		rt_kprintf("devInfo->port      = %d\n",devInfo->port);
		rt_kprintf("devInfo->vbat      = %d %\n",devInfo->vbat);
		rt_kprintf("devInfo->save      = %X\n",devInfo->save);
		rt_kprintf("devInfo->cycle     = %d S\n",devInfo->cycle);
		if(devInfo->save == DEV_INIT_SAVE_FLAGE)//已经保存
		{
			if(devInfo->regFlag == 0)//没有注册要通知设备注册
			{
				update_event_mail(PRO_EVT_REG);//发送注册事件
			}
			rt_kprintf("devInfo->cycle = %d\n",devInfo->cycle);
			set_system_stop_cycle(devInfo->cycle);//更新停机休眠时间。
			//devInfo->sleep++;
			//devinfo_save();
		}
		else//第一次运行
		{
			devInfo->mac = 0xffffffff;
			rt_kprintf("mac:%d",devInfo->mac );
			devInfo->regFlag = 0;
			devInfo->flow = 0;//初始化流量
			devInfo->charge = 0;//初始化充电次数
			devInfo->port = SERVER_PORT;//默认端口
			devInfo->cycle = RTC_ALARM_WAKEUP_TIME;//默认
			rt_memset(devInfo->url,0,32);
			rt_memcpy(devInfo->url, SERVER_IP, rt_strlen(SERVER_IP));
			devInfo->save = DEV_INIT_SAVE_FLAGE;
			devinfo_set(devInfo);
			result = devinfo_save();
			if(result != RT_EOK)
			{
				rt_kprintf("sys eeprom save data error %d\n",__LINE__);
				rt_thread_delay(100);
			}
			rt_kprintf("eeprom save ok\n");
			set_bkp1_reg(0);
			save_bkp_askfail_num(0);//查询寄存器初始化0次
			sys_reboot();
		}
	}

	return result;
}


void ask_evt_result_process(rt_err_t err)
{
	//这个函数没调用一次RAM都会丢失所以只能用备份寄存器
	static rt_uint16_t cnt=0;
	devInfodef *info;

	cnt = load_bkp_askfail_num();//查询服务器失败的次数
	info = devinfo_get();//获取设备参数
	if(err == RT_EOK)//询问成功
	{
		set_system_stop_cycle(info->cycle);
	}
	else//询问失败
	{
		cnt++;
		if((cnt < PROCESS_ERR_MAX)&&((cnt*ERR_SLEEP_CYCLE)<=info->cycle))//处理事件失败，递增尝试
		{
			set_system_stop_cycle(cnt*ERR_SLEEP_CYCLE);
		}
		else
		{
			set_system_stop_cycle(info->cycle);
		}
	}
	save_bkp_askfail_num(cnt);
}


void protocol_thread_entry(void *arg)
{
	rt_err_t runResult = RT_EOK;
	rt_uint8_t updateErr = 0;

	rt_kprintf("%s\n",__FUNCTION__);
	//线程进入工作状态
	rt_thread_entry_work(rt_thread_self());
	
	if(rt_pin_read(KEY_GPIO_PIN) == 1)
	{
		rt_kprintf("key Trigger\n");
		update_event_mail(PRO_EVT_KEY);
	}
	else
	{
		update_event_mail(PRO_EVT_ASK);
	}
	//cur_date_show();

	//打开gprs串口
	gprs_module_uart_crl(1);//打开模块串口

	rt_pin_mode(GSM_POWR_PIN,PIN_MODE_OUTPUT);	//电源
	rt_pin_write(GSM_POWR_PIN, 0);

	devinfo_init_process();
	load_bkp_sys_flow();//加载流量
	//查询设备是否已经注册

	//eeprom_test();
	//固定时间刷新屏幕维持显示效果
	cycle_update_show();
	if(!(read_rtc_bkp1() & SYS_EVT_WAKEUP))//睡眠起来的不用更新
	{
		eeprom_load_data(elsPicBuf1);
		//epd_show_update(2,1,elsPicBuf1,RT_NULL);
		send_epd_mail(EPD_EVT_FULL);
	}
	//eeprom_load_data(elsPicBuf1);
	//send_epd_mail(EPD_EVT_FULL);//调试显示
	
	vbat_init_process();//备份电池处理

	cur_date_show();
	Display();
	while(1);
	while(1)
	{	
		rt_uint32_t evt;

		runResult = rt_event_recv(update_evt,PRO_EVT_KEY|PRO_EVT_ASK|PRO_EVT_REG|
																				 PRO_EVT_UAT|PRO_EVT_URL,
																				 RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,
																				 10,&evt);
		#ifdef USING_PowerManage
		rt_thread_entry_work(rt_thread_self());
		#endif
		if(runResult == RT_EOK)
		{
			devInfodef *info;

			info = devinfo_get();
			rt_kprintf("recv event %x reg =%d mac=%d == ",evt,info->regFlag,info->mac);
			if((evt & PRO_EVT_KEY) && (info->regFlag == 1))//按键强制更新,已经注册了才可以
			{
				rt_err_t result;
				
				rt_kprintf("PRO_EVT_KEY\n");
				result = update_server_pic(&updateErr,evt);
				ask_evt_result_process(result);//事件结果处理优化
			}
			if((evt & PRO_EVT_ASK) && (info->regFlag == 1))//rtc自动更新，已经注册了才可以
			{
				rt_err_t result;
				
				rt_kprintf("PRO_EVT_ASK\n");
				result = dev_server_ask();//设备查询服务器
				ask_evt_result_process(result);//事件结果处理优化
			}
			if(evt & PRO_EVT_REG)//注册设备
			{
				rt_kprintf("PRO_EVT_REG\n");
				dev_server_reg();
			}
			if(evt & PRO_EVT_UAT)
			{
				rt_kprintf("PRO_EVT_UAT\n");
				server_mod_sleep();
			}
			if(evt & PRO_EVT_URL)
			{
				rt_kprintf("PRO_EVT_URL\n");
				server_update_url();
			}
		}
		else
		{
			//系统进入休眠模式
			#ifdef USING_PowerManage
			rt_thread_entry_sleep(rt_thread_self());
			#endif
		}
	}
}

int protocol_thread_init(void)
{
	rt_thread_t thread_id;

	update_evt = rt_event_create("update", RT_IPC_FLAG_FIFO);
	RT_ASSERT(update_evt);

	epd_timer_init();

	thread_id = rt_thread_create("proto",
							  protocol_thread_entry,RT_NULL,
							  512,20,25);
	if(thread_id != RT_NULL)
	{
		rt_thread_startup(thread_id);
	}
	return 0;
}
INIT_APP_EXPORT(protocol_thread_init);




